<template>
  <div class="edit custom-scrollbar">
    <div class="title">角色组编辑</div>
    <div class="main custom-scrollbar">
      <div class="jcxx_box">
        <subtitle title="基础信息" />
        <el-form
          ref="editRef"
          class="editForm"
          :model="editform"
          :rules="editRules"
          label-width="auto"
        >
          <el-form-item label="角色组名称" prop="roleName">
            <el-input v-model="editform.roleName" placeholder="请输入" />
          </el-form-item>
          <el-form-item label="角色组编码" prop="roleCode">
            <el-input v-model="editform.roleCode" placeholder="请输入" />
          </el-form-item>
          <el-form-item label="所属平台" prop="platformId">
            <el-select
              v-model="editform.platformId"
              filterable
              placeholder="请选择"
              disabled
            >
              <el-option
                v-for="item in store.sysPageData"
                :key="item.platformId"
                :label="item.platformName"
                :value="item.platformId"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <div class="content">
        <subtitle title="菜单功能权限" />
        <div class="cont_main">
          <div class="tree_box custom-scrollbar">
            <el-input
              v-model="filterText"
              placeholder="请输入搜索内容"
              clearable
            />
            <el-tree
              class="tree custom-scrollbar"
              ref="treeRef"
              node-key="id"
              show-checkbox
              check-strictly
              highlight-current
              :data="editform.menuAndFunctionVoList"
              :props="defaultProps"
              :check-on-click-node="false"
              :default-expand-all="true"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              @node-click="handle_tree"
              @check="handle_chedk"
            ></el-tree>
          </div>
          <el-table
            ref="userRef"
            style="height: 100%"
            :data="funcData.functionDtoList"
          >
            <el-table-column>
              <template #header>
                <div class="header">
                  <div class="info">所属菜单：{{ menuName }}</div>
                </div>
              </template>
              <el-table-column width="55" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.flag" />
                </template>
              </el-table-column>
              <el-table-column
                label="功能名称"
                prop="functionName"
                align="center"
              />
              <el-table-column
                label="功能值"
                prop="functionId"
                align="center"
              />
            </el-table-column>
          </el-table>
        </div>
        <subtitle title="角色组权限" />
        <div class="user_box">
          <div class="user_tab">
            <el-table
              border
              ref="userRef"
              style="height: 100%"
              :data="userData"
            >
              <el-table-column>
                <template #header>
                  <div class="header">
                    <div class="info">
                      可选用户({{
                        userData.filter((item) => !item.flag).length
                      }})
                    </div>
                    <el-input
                      v-model="userDataVal"
                      placeholder="请输入用户名或姓名"
                      @input="leftInput"
                    />
                  </div>
                </template>
                <el-table-column width="55" align="center">
                  <template #header>
                    <el-checkbox
                      v-model="leftChecksFlag"
                      :disabled="disabledusers()"
                    />
                  </template>
                  <template #default="scope">
                    <el-checkbox
                      v-model="scope.row.flag"
                      :disabled="disabledUser(scope.row)"
                      @change="change_leftCheck(scope.row)"
                    />
                  </template>
                </el-table-column>
                <el-table-column
                  label="用户名"
                  prop="username"
                  align="center"
                />
                <el-table-column label="姓名" prop="fullname" align="center" />
              </el-table-column>
            </el-table>
            <el-pagination
              size="small"
              layout="total,prev, slot, next"
              background
              v-model:current-page="leftPage.page"
              v-model:page-size="leftPage.pageSize"
              :total="leftPage.total"
              @current-change="get_user()"
            >
              <div class="pagination">
                <el-input
                  size="small"
                  v-model.number="leftPage.page"
                  style="width: 40px"
                  @blur="leftPageInput"
                  @input="handleLeftInput"
                />
                <span
                  >/ {{ Math.ceil(leftPage.total / leftPage.pageSize) }}</span
                >
              </div>
            </el-pagination>
          </div>
          <div class="user_cont">
            <el-button :icon="ArrowLeft" @click="handle_left" />
            <el-button :icon="ArrowRight" @click="handle_right" />
          </div>
          <div class="user_tab">
            <el-table border style="height: 100%" :data="userList">
              <el-table-column>
                <template #header>
                  <div class="header">
                    <div class="info">已选用户({{ userList.length }})</div>
                    <el-input
                      v-model="userListVal"
                      placeholder="请输入用户名或姓名"
                      @input="rightInput"
                    />
                  </div>
                </template>
                <el-table-column width="55" align="center">
                  <template #header>
                    <el-checkbox v-model="rightChecksFlag" />
                  </template>
                  <template #default="scope">
                    <el-checkbox
                      :model-value="!scope.row.flag"
                      @change="scope.row.flag = !scope.row.flag"
                    />
                  </template>
                </el-table-column>
                <el-table-column
                  label="用户名"
                  prop="username"
                  align="center"
                />
                <el-table-column label="姓名" prop="fullname" align="center" />
              </el-table-column>
            </el-table>
            <el-pagination
              size="small"
              layout="total,prev, slot, next"
              background
              v-model:current-page="rightPage.page"
              v-model:page-size="rightPage.pageSize"
              :total="rightPage.total"
              @current-change="rightPageInput"
            >
              <div class="pagination">
                <el-input
                  size="small"
                  style="width: 40px"
                  v-model="rightPage.page"
                  @input="handleRightInput"
                  @blur="rightPageInput"
                />
                <span
                  >/
                  {{
                    Math.ceil(rightPage.total / rightPage.pageSize)
                      ? Math.ceil(rightPage.total / rightPage.pageSize)
                      : 1
                  }}</span
                >
              </div>
            </el-pagination>
          </div>
        </div>
        <div class="button_box">
          <el-button @click="cancel(editRef)">取消</el-button>
          <el-button type="primary" @click="confirm(editRef)">确定</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { getRoleById, updateRole } from "@/api/appPlatfor";
import subtitle from "@/components/subtitle.vue";
import { useStore } from "@/store";
import { useRoute, useRouter } from "vue-router";
import { computed, onMounted, reactive, ref, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import { userpage } from "@/api/basic";

const store = useStore();
const route = useRoute();
const router = useRouter();

const editRef = ref(null);
const editform = reactive({});
//校验规则
const customValidator = (rule, value, callback) => {
  let length = 0;
  for (let i = 0; i < value.length; i++) {
    if (value.charCodeAt(i) > 127 || value.charCodeAt(i) == 94) {
      length += 2;
    } else {
      length++;
    }
  }
  if (length > 30) {
    callback(new Error("最大不能超过30个字符，汉字为两个字符"));
  } else {
    callback();
  }
};
const editRules = reactive({
  platformId: [
    { required: true, message: "请选择所属平台", trigger: "change" },
  ],
  roleName: [
    { required: true, message: "请输入角色组名称", trigger: "blur" },
    { validator: customValidator, trigger: "blur" },
  ],
  roleCode: [
    { required: true, message: "请输入角色组编码", trigger: "blur" },
    { validator: customValidator, trigger: "blur" },
  ],
});
const treeRef = ref(null);
const treeData = ref([]);
const filterText = ref("");
const defaultProps = reactive({
  children: "children",
  label: "menuName",
  value: "id",
});
const menuName = ref("");
const funcData = ref([]);
const roleInfoDtoList = reactive([]);

const leftUserData = ref([]);
const userData = ref([]);
const userDataVal = ref("");
const leftPage = reactive({
  page: 1,
  pageSize: 1000,
  total: 0,
});
const rightUserData = ref([]);
const userList = ref([]);
const userListVal = ref("");
const rightPage = reactive({
  page: 1,
  pageSize: 1000,
  total: 0,
});
const userIdList = ref([]);

const leftChecksFlag = computed({
  get() {
    return userData.value.every((item) => item.flag);
  },
  set(value) {
    userData.value.forEach((item) => (item.flag = value));
    if (value) {
      checkList.value = JSON.parse(JSON.stringify(userData.value));
    } else {
      checkList.value = [];
    }
  },
});

const rightChecksFlag = computed({
  get() {
    if (userList.value.length > 0) {
      return userList.value.every((item) => !item.flag);
    }
    return false;
  },
  set(value) {
    userList.value.forEach((item) => (item.flag = !value));
  },
});

//点击菜单
function selectParent(node) {
  let currentNode = node;

  while (currentNode.parent) {
    currentNode = currentNode.parent;
    currentNode.data.flag = true;
    treeRef.value.setChecked(currentNode.data, true, false);
  }
}
const handle_tree = (data, node) => {
  funcData.value = {};
  if (data.flag) {
    funcData.value = data;
  }
  menuName.value = data.menuName;
};

const handle_chedk = (data) => {
  menuName.value = data.menuName;
  let node = treeRef.value.getNode(data);
  data.flag = !data.flag;
  funcData.value = {};
  if (data.flag) {
    funcData.value = data;
  }
  selectParent(node);
  if (data.children.length > 0) {
    if (!data.flag) {
      data.children.forEach((item) => {
        item.flag = false;
        treeRef.value.setChecked(item, false, false);
      });
    }
  }
};

//用户列表选择
const leftInput = (val) => {
  if (!val) {
    // 当输入为空时，恢复原始数据
    userData.value = [...leftUserData.value]; // 使用展开运算符来确保响应性
  } else {
    // 过滤数据
    userData.value = leftUserData.value.filter((item) => {
      return item.fullname.includes(val) || item.username.includes(val);
    });
  }
};

const rightInput = (val) => {
  if (!val) {
    userList.value = rightUserData.value;
  }
  userList.value = rightUserData.value.filter((item) => {
    return item.fullname.includes(val) || item.username.includes(val);
  });
};
const handle_left = () => {
  userList.value = userList.value.filter((item) => item.flag);
  checkList.value = userData.value.filter((item) => item.flag);
  rightUserData.value = userList.value;
};
const checkList = ref([]);
const change_leftCheck = (row) => {
  if (row.flag) {
    checkList.value.push({ ...row });
  } else {
    checkList.value = checkList.value.filter((item) => item.id !== row.id);
  }
};
const handle_right = () => {
  let arr = Array.from(checkList.value);

  rightUserData.value = JSON.parse(JSON.stringify(arr));
};
const disabledUser = (row) => {
  let ind = rightUserData.value.findIndex((item) => item.id === row.id);
  if (ind > -1) {
    userData.value.forEach((item) => {
      if (item.id === row.id) {
        item.flag = true;
      }
    });
    return true;
  }
};

const disabledusers = () => {
  return userData.value.every((item) => {
    return rightUserData.value.some((bigItem) => bigItem.id === item.id);
  });
};

const leftPageInput = () => {
  if (!leftPage.page) {
    leftPage.page = 1;
  }
  get_user();
};
const rightPageInput = () => {
  if (!rightPage.page) {
    rightPage.page = 1;
  }
  const startIndex = (rightPage.page - 1) * rightPage.pageSize;
  const endIndex = startIndex + rightPage.pageSize;
  userList.value = rightUserData.value.slice(startIndex, endIndex);
};
const handleLeftInput = (value) => {
  leftPage.page = Number(value.replace(/[^\d]/g, ""));
};
const handleRightInput = (value) => {
  rightPage.page = Number(value.replace(/[^\d]/g, ""));
};

watch(rightUserData, () => {
  rightPage.total = rightUserData.value.length;
  const startIndex = (rightPage.page - 1) * rightPage.pageSize;
  const endIndex = startIndex + rightPage.pageSize;
  userList.value = rightUserData.value.slice(startIndex, endIndex);
});

//确定修改
const confirm = (formEl) => {
  if (!formEl) return;
  formEl.validate(async (valid) => {
    if (valid) {
      const res = await updateRole({
        id: editform.id,
        roleName: editform.roleName,
        roleCode: editform.roleCode,
        platformId: editform.platformId,
        roleInfoDtoList: roleInfoDtoList,
        userIdList: userIdList.value,
      });

      if (res.code === 200) {
        router.push("/app-platfor/roleGroup");
        ElMessage({
          type: "success",
          message: res.msg,
        });
      }
    }
  });
};

//取消
const cancel = (formEl) => {
  ElMessageBox.confirm("确定取消修改角色组吗？", {
    type: "error",
    distinguishCancelAndClose: true,
    confirmButtonText: "确定",
    cancelButtonText: "取消",
  })
    .then(() => {
      formEl.resetFields();
      router.push("/app-platfor/roleGroup");
    })
    .catch(() => {});
};

//过滤菜单功能
watch(filterText, (val) => {
  treeRef.value.filter(val);
});
const filterNode = (value, data) => {
  if (!value) return true;
  return data.menuName.includes(value);
};
//回显树形结构选中状态
function filterChecked(tree) {
  const arr = [];

  function traverseTree(node) {
    node.forEach((item) => {
      if (item.flag === true) {
        arr.push(item.id);
      }
      if (item.children) {
        traverseTree(item.children);
      }
    });
  }

  traverseTree(tree);
  treeRef.value.setCheckedKeys(arr, true);
}
//更新 roleInfoDtoList
function updateRoleInfoDtoList() {
  roleInfoDtoList.length = 0;
  function traverseTree(nodes) {
    nodes.forEach((node) => {
      // 创建一个空数组来存放当前节点的 functionIdList
      let currentNodeFunctionIdList = [];

      // 遍历 node.functionDtoList 来填充 currentNodeFunctionIdList
      node.functionDtoList.forEach((functionItem) => {
        if (functionItem.flag) {
          // 如果 flag 为 true，将 functionItem 的 id 添加到 currentNodeFunctionIdList
          currentNodeFunctionIdList.push(functionItem.id);
        }
      });

      if (node.flag) {
        roleInfoDtoList.push({
          menuId: node.id,
          functionIdList: currentNodeFunctionIdList,
        });
      }

      // 如果节点有子节点，递归遍历子节点
      if (node.children) {
        traverseTree(node.children);
      }
    });
  }

  // 开始遍历树形数据
  traverseTree(editform.menuAndFunctionVoList);
}
//监听treeData，更新roleInfoDtoList
watch(editform, updateRoleInfoDtoList, { deep: true });
//监听角色组
watch(
  userList,
  (newUserList, oldUserList) => {
    userIdList.value = [];
    newUserList.forEach((user) => {
      userIdList.value.push(user.id);
    });
  },
  { deep: true }
);
//获取用户
const get_user = async () => {
  const res = await userpage({
    page: leftPage.page,
    pageSize: leftPage.pageSize,
  });
  if (res.code === 200) {
    leftUserData.value = res.data.data;
    userData.value = res.data.data;
    leftPage.total = res.data.count;
  }
};

const init = async () => {
  const res = await userpage({});
  let arr = [];
  editform.userVoList.forEach((item) => {
    res.data.data.forEach((v) => {
      if (item.id === v.id) {
        item.flag = true;
        v.flag = true;
        arr.push(v);
      } else {
        item.flag = false;
      }
    });
  });
  rightUserData.value = JSON.parse(JSON.stringify(arr));
  checkList.value = JSON.parse(JSON.stringify(arr));
};
//获取编辑数据
const get_edit = async () => {
  const res = await getRoleById({
    id: route.query.id,
    platformId: route.query.platformId,
  });
  if (res.code === 200) {
    Object.assign(editform, res.data);
    filterChecked(res.data.menuAndFunctionVoList);
    get_user();

    init();
  }
};

onMounted(() => {
  get_edit();
  store.getSysPage();
});
</script>

<style lang="scss" scoped>
.edit {
  width: 100%;
  height: 100%;
  padding: 0 20px;
  background: #fff;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  .title {
    font-size: 20px;
    font-weight: bold;
    line-height: 2;
  }
  .main {
    flex: 1;
    width: 100%;
    padding: 5px 20px 5px 15px;
    display: flex;
    flex-direction: column;
    .jcxx_box {
      width: 100%;
      .editForm {
        width: 100%;
        padding: 15px 0;
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
        gap: 10px 25px;
        .el-form-item {
          width: calc(50% - 50px);
        }
      }
    }
    .content {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 10px;
      .cont_main {
        flex: 1;
        min-height: 200px;
        max-height: 400px;
        display: flex;
        gap: 15px;
        .tree_box {
          width: 360px;
          display: flex;
          flex-direction: column;
          gap: 10px;
          .tree {
            flex: 1;
            padding: 10px;
            border-radius: 5px;
            border: 1px solid #ccc;
            overflow-y: auto;
          }
        }
      }
      .user_box {
        width: 100%;
        min-height: 200px;
        max-height: 500px;
        display: flex;
        gap: 10px;
        .user_tab {
          flex: 7;
          display: flex;
          flex-direction: column;
          > .el-table {
            flex: 1;
          }
          .el-pagination {
            width: 100%;
            height: 40px;
            display: flex;
            justify-content: right;
            align-items: center;
            .pagination {
              margin: 0 10px;
              display: flex;
              justify-content: center;
              align-items: center;
              gap: 3px;
              span {
                color: #606266;
              }
            }
          }
          .header {
            display: flex;
            align-items: center;
            gap: 10px;
            .info {
              white-space: nowrap;
            }
          }
        }
        .user_cont {
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          gap: 15px;
          > .el-button {
            margin: 0;
          }
        }
      }
      .button_box {
        width: 100%;
        height: 50px;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }
}

/* 自定义滚动条样式 */
.custom-scrollbar::-webkit-scrollbar {
  width: 5px; /* 滚动条宽度 */
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  cursor: pointer; /* 鼠标悬停时显示指针形状 */
  background: #d0d0d2; /* 滑块背景颜色 */
  border-radius: 10px; /* 滑块圆角 */
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: #f1f1f1; /* 轨道背景颜色 */
  border-radius: 10px; /* 轨道圆角 */
}
</style>